package cn.wildfirechat.voipdemo;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.*;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.sdk.RobotService;
import cn.wildfirechat.sdk.UserAdmin;
import cn.wildfirechat.sdk.model.IMResult;
import cn.wildfirechat.voipdemo.call.CallService;
import cn.wildfirechat.voipdemo.push.PushMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;

import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import static cn.wildfirechat.sdk.utilities.JsonUtils.gson;

@org.springframework.stereotype.Service
public class ServiceImpl {
    private static final Logger LOG = LoggerFactory.getLogger(ServiceImpl.class);

    @Value("${push.server.uri}")
    private String pushServerUri;

    @Autowired
    private RobotConfig mRobotConfig;

    private RobotService robotService;

    @Autowired
    private CallService callService;

    @PostConstruct
    private void init() {
        robotService = new RobotService(mRobotConfig.im_url, mRobotConfig.im_id, mRobotConfig.im_secret);
    }

    public void StartPrivateCall(String cid) {
        LOG.info("start private call   ", mRobotConfig.im_id, mRobotConfig.im_secret);
        Conversation conversation = new Conversation();
        conversation.setType(ProtoConstants.ConversationType.ConversationType_Private);
        conversation.setTarget(cid);
        conversation.setLine(0);

        pushMessage(null, "comeissofttechvip", cid, "jj", null);

        try {
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        callService.startPrivateCall(conversation, true, false);

        // pushMessage(null, "comeissofttechvip", cid, "jj");
    }

    @Async
    public void sendCall(JSONObject jsonStr) {
        LOG.info("技师call request {} {} {}", mRobotConfig.im_id, mRobotConfig.im_secret, jsonStr.toString());
        String phone = jsonStr.getStr("phone");
        String pkg = jsonStr.getStr("pkg");
        String type = jsonStr.getStr("type");
        if (StrUtil.isEmpty(phone)) {
            return;
        }
        if (StrUtil.isEmpty(pkg)) {
            return;
        }
        if (StrUtil.isEmpty(type)) {
            return;
        }
        JSONObject pushData = jsonStr.getJSONObject("pushData");
        if (jsonStr.containsKey("pushData") && ObjectUtil.isNull(pushData)) {
            return;
        }

        String[] phones = phone.split(",");
        for (String p : phones) {
            if (StrUtil.isEmpty(p)) {
                continue;
            }
            String cid = null;
            try {
                IMResult<InputOutputUserInfo> userRes = UserAdmin.getUserByMobile(p);
                LOG.info("getUserByMobile res {}", gson.toJson(userRes));
                if (userRes.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
                    InputOutputUserInfo userInfo = userRes.getResult();
                    if (ObjectUtil.isNotNull(userInfo)) {
                        cid = userInfo.getUserId();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (StrUtil.isEmpty(cid)) {
                continue;
            }

            Conversation conversation = new Conversation();
            conversation.setType(ProtoConstants.ConversationType.ConversationType_Private);
            conversation.setTarget(cid);
            conversation.setLine(0);

//            try {
//                Thread.sleep(RandomUtil.randomLong(2001, 2999));
//            } catch (InterruptedException e) {}

            pushMessage(null, pkg, cid, type, pushData);
        }
    }

    public void onReceiveMessage(OutputMessageData messageData) {
        LOG.info("on receive message {}", gson.toJson(messageData));

        if (messageData.getPayload().getType() >= 400 && messageData.getPayload().getType() <= 420) {
            callService.onReceiveCallMessage(messageData);
            return;
        }

        if (messageData.getPayload().getType() == 1
                && ("给我打电话".equals(messageData.getPayload().getSearchableContent()) || "给我打个电话".equals(messageData.getPayload().getSearchableContent()) || "call me".equalsIgnoreCase(messageData.getPayload().getSearchableContent()))
                && (messageData.getConv().getType() == ProtoConstants.ConversationType.ConversationType_Private || messageData.getConv().getType() == ProtoConstants.ConversationType.ConversationType_Group)) {
            if (messageData.getConv().getType() == ProtoConstants.ConversationType.ConversationType_Private) {
                //单聊的target为对方id，收到的消息需要设置一下target。
                messageData.getConv().setTarget(messageData.getSender());
            }

            if (callService.hasPreferEngine(messageData.getSender())) {
                if (messageData.getConv().getType() == ProtoConstants.ConversationType.ConversationType_Private) {
                    LOG.info("start private call  ===> ", gson.toJson(messageData.getConv()), callService.isAdvanceEngine(messageData.getSender()));
                    callService.startPrivateCall(messageData.getConv(), false, callService.isAdvanceEngine(messageData.getSender()));
                } else {
                    callService.startGroupCall(messageData.getConv(), Arrays.asList(messageData.getSender()), false, callService.isAdvanceEngine(messageData.getSender()));
                }
            } else {
                MessagePayload payload = new MessagePayload();
                payload.setType(1);
                payload.setSearchableContent("请先给我打个电话，以后我才能给您电话");
                try {
                    IMResult<SendMessageResult> result = robotService.sendMessage(mRobotConfig.im_id, messageData.getConv(), payload);
                    if (result != null) {
                        if (result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
                            LOG.info("Send response success");
                        } else {
                            LOG.error("Send response error {}", result.getCode());
                        }
                    } else {
                        LOG.error("Send response is null");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    LOG.error("Send response execption");
                }
            }
            return;
        }
        return;
    }

    public void onReceiveConferenceEvent(String event) {
        callService.onConferenceEvent(event);
    }


    public void pushMessage(PushMessage pushMessage, String pkg, String targetId, String fromUId, JSONObject pushData) {
        if (ObjectUtil.isNull(pushMessage)) {
            pushMessage = new PushMessage();
        }
        pushMessage.messageId = System.currentTimeMillis() / 1000;

        // 对应机器人 UpBell DownBell ArriveBell AddBell TimeOutBell    FireRobot = 上下钟提醒
        pushMessage.sender = fromUId;
        pushMessage.senderName = fromUId;

        pushMessage.pushMessageType = 1;
        pushMessage.pushType = 0;
        if (StrUtil.isEmpty(pkg)) {
            pushMessage.packageName = "comeissofttechvip";
        } else {
            pushMessage.packageName = pkg;
        }
        pushMessage.target = "9ygqmws2k";
        pushMessage.targetName = "jj";
        pushMessage.convType = 1;
        pushMessage.line = 0;
        pushMessage.cntType = 1;

        if (ObjectUtil.isNull(pushData)) {
            pushData = new JSONObject();
        }

        String sender = pushMessage.sender;
        String sound = "";
        String sendrTitle = "";
        if (sender.equals("UpBell")) {
            sound = "clock.caf";
            sendrTitle = "上钟提醒";
        } else if (sender.equals("DownBell")) {
            sound = "finished.caf";
            sendrTitle = "下钟提醒";
        } else if (sender.equals("ArriveBell")) {
            sound = "approach.caf";
            sendrTitle = "到钟提醒";
        } else if (sender.equals("AddBell")) {
            sound = "addclock.caf";
            sendrTitle = "加钟提醒";
        } else if (sender.equals("TimeOutBell")) {
            sound = "overclock.caf";
            sendrTitle = "超时提醒";
        } else if (sender.equals("AlertWarn")) {
            sound = "alert.caf";
            sendrTitle = "告警提醒";
        } else if (sender.equals("AlertWarn2")) {
            sound = "alert2.caf";
            sendrTitle = "告警提醒";
        } else if (sender.equals("AppointmentBell")) {
            sound = "book.caf";
            sendrTitle = "预约提醒";
        } else if (sender.equals("WaitBell")) {
            sound = "wait.caf";
            sendrTitle = "等待提醒";
        }

        if (ObjectUtil.isNotNull(pushData)) {
            if (!pushData.containsKey("audioOnly") || StrUtil.isEmpty(pushData.getStr("audioOnly"))) {
                pushData.put("audioOnly", true);
            }
            if (!pushData.containsKey("callId") || StrUtil.isEmpty(pushData.getStr("callId"))) {
                pushData.put("callId", pushMessage.sender);
            }
            if (!pushData.containsKey("ring") || StrUtil.isEmpty(pushData.getStr("ring"))) {
                pushData.put("ring", sound);
            }
            if (!pushData.containsKey("title") || StrUtil.isEmpty(pushData.getStr("title"))) {
                pushData.put("title", sendrTitle);
            }
            pushMessage.pushData = pushData.toString();
        } else {
            Map<String, Object> map = new HashMap<>();
            map.put("audioOnly", true);
            map.put("callId", pushMessage.sender);
            map.put("ring", sound);
            map.put("title", sendrTitle);
            pushMessage.pushData = gson.toJson(map);
        }

        pushMessage.voipDeviceToken = "1B2234B7B3AA279D7CDDE215AD62CA914FC9B46268CF2EF065171FBC25C20782";

        try {
            IMResult<InputOutputUserInfo> userRes = UserAdmin.getUserByUserId(targetId);
            LOG.info("userRes res {}", gson.toJson(userRes));
            if (userRes.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
                InputOutputUserInfo userInfo = userRes.getResult();
                pushMessage.targetName = userInfo.getDisplayName();
                pushMessage.target = userInfo.getUserId();
            }

            IMResult<GetUserSessionResult> userSession = UserAdmin.getUserSession(targetId);
            LOG.info("getUserSession res {} {}", gson.toJson(userSession), userSession.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS);

            if (userSession.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
                GetUserSessionResult result = userSession.getResult();
                for (GetUserSessionResult.UserSession session : result.userSessions) {
                    // pushMessage.deviceToken = session.deviceToken;
                    LOG.info("getUserSession session {} {}", gson.toJson(session), ObjectUtil.isNotEmpty(session.deviceVoipToken));
                    if (ObjectUtil.isNotEmpty(session.deviceVoipToken)) {
                        pushMessage.voipDeviceToken = session.deviceVoipToken;
                        break;
                    }
                }
//                for (GetUserSessionResult.UserSession session : result.userSessions) {
//                    // pushMessage.deviceToken = session.deviceToken;
//                    if (ObjectUtil.isNotNull(session.deviceToken)) {
//                        pushMessage.deviceToken = session.deviceToken;
//                        break;
//                    }
//                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        LOG.info("**** pushMessage request params : {}", gson.toJson(pushMessage));

        if (StrUtil.isEmpty(pushMessage.voipDeviceToken)) {
            return;
        }

        String pushUri = pushServerUri + "/ios/push/" + pushMessage.packageName;
        // String res = HttpUtil.post(pushUri, gson.toJson(pushMessage));
        String res = HttpRequest.post(pushUri).header("Content-Type", "application/json; charset=utf-8").body(gson.toJson(pushMessage)).execute().body();

        LOG.info("**** pushMessage result: {}", res);
    }

}
